package cn.sh.library.gmwx.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.sh.library.gmwx.base.Constant;
import cn.sh.library.gmwx.bean.InstanceSearchBean;
import cn.sh.library.gmwx.dto.Pager;
import cn.sh.library.gmwx.service.BookService;
import cn.sh.library.gmwx.service.RemoteService;
import cn.sh.library.gmwx.sparql.InstanceSparql;
import cn.sh.library.gmwx.sparql.ItemSparql;
import cn.sh.library.gmwx.sparql.WorkSparql;

@Controller
@RequestMapping("/bibrepo")
public class BibController extends BaseController {
    @Resource
    private BookService bookService;
    @Resource
    private WorkSparql workSparql;
    @Resource
    private InstanceSparql instanceSparql;
    @Resource
    private ItemSparql itemSparql;
    @Resource
    private RemoteService remoteService;

    @ResponseBody
    @RequestMapping(value = "query", method = RequestMethod.POST)
    public Map<String, Object> query(Model model, InstanceSearchBean search, Pager pager){
        Map<String, Object> result = new HashMap<>();

        List<Map<String, String>> list = this.bookService.instances(search, pager);

        result.put("resultList", list);
        result.put("pager", pager);
        return result;
    }

    @ResponseBody
    @RequestMapping(value = "/instance_rdf", method = RequestMethod.GET)
    public void rdf(HttpServletResponse response, String uri){
        ByteArrayOutputStream bos = (ByteArrayOutputStream) instanceSparql.instanceTempModel(uri);
        byte[] data = bos.toByteArray();
        String rdfData = new String(data, Charset.forName("utf-8"));

        response.setContentType("application/rdf+xml");
        try {
            response.getWriter().write(rdfData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ResponseBody
    @RequestMapping(value = "/manage/bib_update_facet", method = RequestMethod.GET)
    public String updateFacet() {
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:date", "time:Instant");
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:place", "shl:Place");
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:agent", "shl:Organization");
        this.instanceSparql.countInstance();

        return "SUCCESS";
    }

    @ResponseBody
    @RequestMapping(value = "facet_year", method = RequestMethod.POST)
    public Map<String, Object> facet_year(Model model, InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:date"));

        return result;
    }

    @ResponseBody
    @RequestMapping(value = "facet_place", method = RequestMethod.POST)
    public Map<String, Object> facet_plc(Model model, InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:place"));

        return result;
    }

    @ResponseBody
    @RequestMapping(value = "facet_publish", method = RequestMethod.POST)
    public Map<String, Object> facet_pub(Model model, InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:agent"));

        return result;
    }

    @RequestMapping(value = "view/{id}", method = RequestMethod.GET)
    public String view(Model model, @PathVariable("id") String id){
        String uri = Constant.PREFIX_INSTANCE + id;
        model.addAttribute("uri", uri);

        //Work Information
        model.addAttribute("info", this.instanceSparql.getBibInfos(uri));
        model.addAttribute("contributions", this.instanceSparql.getContributions(uri));
        model.addAttribute("works", this.instanceSparql.getWorks(uri));

        return "public/insview";
    }

    @ResponseBody
    @RequestMapping(value = "count", method = RequestMethod.POST)
    public Map<String, Object> count(Model model, InstanceSearchBean search){
        Map<String, Object> result = new HashMap<>();

        result.put("year", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:date"));
        result.put("place", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:place"));
        result.put("publish", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:agent"));

        return result;
    }
}
